/* This source file is part of the ATMEL AVR32-SoftwareFramework-1.2.2ES-AT32UC3A Release */

/*This file has been prepared for Doxygen automatic documentation generation.*/
/*! \file *********************************************************************
 *
 * \brief Basic TFTP Server for AVR32 UC3.
 *
 * - Compiler:           GNU GCC for AVR32
 * - Supported devices:  All AVR32 devices can be used.
 * - AppNote:
 *
 * \author               Atmel Corporation: http://www.atmel.setupParallelWritecom \n
 *                       Support and FAQ: http://support.atmel.no/
 *
 *****************************************************************************/

/* Copyright (c) 2007, Atmel Corporation All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * 1. Redistributions of source code must retain the above copyright notice,
 * this list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright notice,
 * this list of conditions and the following disclaimer in the documentation
 * and/or other materials provided with the distribution.
 *
 * 3. The name of ATMEL may not be used to endorse or promote products derived
 * from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY ATMEL ``AS IS'' AND ANY EXPRESS OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY AND
 * SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT,
 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */


/*
  Implements a simplistic TFTP server.

  In order to put data on the TFTP server (not over 2048 bytes)
  tftp 192.168.0.2 PUT <src_filename>
  this will copy file from your hard drive to the RAM buffer of the application

  tftp 192.168.0.2 GET <dst_filename>
  this will copy file from the RAM buffer of the application to your hard drive
  You can then check that src_filename and dst_filename are identical
 */


#if (TFTP_USED == 1)

#include <string.h>

#include "usart.h"


/* Scheduler includes. */
#include "FreeRTOS.h"
#include "task.h"
#include "partest.h"
#include "BasicTFTP.h"


/* Demo includes. */
#include "portmacro.h"

/* lwIP includes. */
#include "lwip/api.h"
#include "lwip/tcpip.h"
#include "lwip/memp.h"
#include "lwip/stats.h"
#include "lwip/opt.h"
#include "lwip/api.h"
#include "lwip/arch.h"
#include "lwip/sys.h"
#include "netif/loopif.h"
#include "lwip/sockets.h"
#include "print_funcs.h"
/**********************added *************/
#include "gpio.h"
#include "board.h"

#define SRQ   AVR32_PIN_PA22
#define EOI AVR32_PIN_PA16        //
#define DAV AVR32_PIN_PA15
#define NRFD AVR32_PIN_PA19        //
#define NDAC AVR32_PIN_PA18        //
#define IFC AVR32_PIN_PA17
#define ATN AVR32_PIN_PA14
#define REN  AVR32_PIN_PA21       //
#define TE  AVR32_PIN_PA26
#define DC  AVR32_PIN_PA25


//GPIB
#define DATA1 AVR32_PIN_PA13        // Service Request
#define DATA2 AVR32_PIN_PA12        // Attention
#define DATA3 AVR32_PIN_PA10        // End Or Identity
#define DATA4 AVR32_PIN_PA04        // Data Valid
#define DATA5 AVR32_PIN_PA03        // Not Ready For Data--------------CHECK
#define DATA6 AVR32_PIN_PA02        // Not Data Accepted
#define DATA7 AVR32_PIN_PA01         // Interface Clear
#define DATA8 AVR32_PIN_PA00


#define nACK  AVR32_PIN_PB16
#define BUSY AVR32_PIN_PB17        //
#define PAPEREND AVR32_PIN_PB18
#define SELECT AVR32_PIN_PB19        //
#define nAUTOLF AVR32_PIN_PB20        //
#define nERROR AVR32_PIN_PB21
#define nINIT AVR32_PIN_PB22
#define nSELECTIN  AVR32_PIN_PB27       //
#define nSTROBE AVR32_PIN_PA28       //  CHECK IF VALID!!!!!!!!!!!!!!



//DATA LINES
//TEMP SHARED BY PARALLEL-GPIB
// PARALLEL


/*
#define DATA1 AVR32_PIN_PA29        // Service Request
#define DATA2 AVR32_PIN_PA30        // Attention
#define DATA3 AVR32_PIN_PB04        // End Or Identity
#define DATA4 AVR32_PIN_PB10        // Data Valid
#define DATA5 AVR32_PIN_PB11        // Not Ready For Data--------------CHECK
#define DATA6 AVR32_PIN_PB12        // Not Data Accepted
#define DATA7 AVR32_PIN_PB13         // Interface Clear
#define DATA8 AVR32_PIN_PB14

*/
/********************stop adding *************************/


#define O_WRONLY 1
#define O_RDONLY 2


/* The port on which we listen. */
#define TFTP_PORT    ( 69 )

/* Delay on close error. */
#define TFTP_DELAY         ( 10 )

/* Delay on bind error. */
#define TFTP_ERROR_DELAY    ( 40 )

#define TFTP_LED     ( 4 )

/***added function headers **********************/
void init_GPIB();
void enablePins();
int readGPIB(char *in_address);
void SetListenerTalker(char c);
void setPinsDependingOnData(char c);
char *chartobin ( unsigned char c );
char binaryToAscii(int buffer[]);
int* createDataChar();
void SetDataLines(char controls[]);
void SetControlLines(char controls[]);
void setPinsDependingOnData(char c);
void RcvBinData();
int sendGPIBData(char *address, char *data, int size);
int usb2ser(char *data, int length);
int connectClient();
void readParallel();
void setupParallelWrite();
int readGPIBWF(char *in_address);

char serialRead[1024];
int stringPlace = 0;
int clientfd;

int dummyFunction();
void usb2par(char *data, int length);
void readControlPins();
void readDataPins();

/***************stop adding *****************/

char data_out[SEGSIZE+sizeof(struct tftphdr)];
char data_in[SEGSIZE+sizeof(struct tftphdr)];

//struct tftp_server *server;

/*------------------------------------------------------------*/
static char * errmsg[] = {
		"Undefined error code",               // 0 nothing defined
		"File not found",                     // 1 TFTP_ENOTFOUND
		"Access violation",                   // 2 TFTP_EACCESS
		"Disk full or allocation exceeded",   // 3 TFTP_ENOSPACE
		"Illegal TFTP operation",             // 4 TFTP_EBADOP
		"Unknown transfer ID",                // 5 TFTP_EBADID
		"File already exists",                // 6 TFTP_EEXISTS
		"No such user",                       // 7 TFTP_ENOUSER
};


/* Send an error packet to the client */
static void
tftpd_send_error(int s, struct tftphdr * reply, int err,
		struct sockaddr_in *from_addr, int from_len)
{
	if ( ( 0 <= err ) && ( sizeof(errmsg)/sizeof(errmsg[0]) > err) ) {
		reply->th_opcode = htons(ERROR);
		reply->th_code = htons(err);
		if ( (0 > err) || (sizeof(errmsg)/sizeof(errmsg[0]) <= err) )
			err = 0; // Do not copy a random string from hyperspace
		strcpy(reply->th_msg, errmsg[err]);
		sendto(s, reply, 4+strlen(reply->th_msg)+1, 0,
				(struct sockaddr *)from_addr, from_len);
	}
}

portCHAR cRamBuffer[2048];
int lCurrentBlock = 0;
int lTotalLength = 0;


int tftpd_close_data_file(int fd)
{
	lCurrentBlock = 0;
	return (5);
}

int tftpd_open_data_file(int fd, int mode)
{
	lCurrentBlock = 0;
	return (5);
}

int tftpd_read_data_file(int fd, portCHAR * buffer, int length)
{
	int lReturnValue;

	if ((lTotalLength -= length) >= 0) {
		lReturnValue = length;
	}
	else
	{
		lReturnValue = lTotalLength + length;
		lTotalLength = 0;
	}
	memcpy(buffer, &cRamBuffer[lCurrentBlock * SEGSIZE], lReturnValue);
	lCurrentBlock++;
	return (lReturnValue);
}

//
// callback to store data to the RAM buffer
//
int tftpd_write_data_file(int fd, portCHAR * buffer, int length)
{
	lTotalLength += length;
	memcpy(&cRamBuffer[lCurrentBlock * SEGSIZE], buffer, length);
	lCurrentBlock++;
	return (length);
}

//
// Receive a file from the client
//
static void
tftpd_write_file(struct tftphdr *hdr,
		struct sockaddr_in *from_addr, int from_len)
{

	struct tftphdr *reply = (struct tftphdr *)data_out;
	struct tftphdr *response = (struct tftphdr *)data_in;
	int fd, len, ok, tries, closed, data_len, s;
	unsigned short block;
	struct timeval timeout;
	fd_set fds;
	int total_timeouts = 0;
	struct sockaddr_in client_addr, local_addr;
	int client_len;


	s = socket(AF_INET, SOCK_DGRAM, 0);
	if (s < 0) {
		return;
	}

	memset((char *)&local_addr, 0, sizeof(local_addr));
	local_addr.sin_family = AF_INET;
	local_addr.sin_len = sizeof(local_addr);
	local_addr.sin_addr.s_addr = htonl(INADDR_ANY);
	local_addr.sin_port = htons(INADDR_ANY);

	if (bind(s, (struct sockaddr *)&local_addr, sizeof(local_addr)) < 0) {
		// Problem setting up my end
		close(s);
		return;
	}

	if ((fd = tftpd_open_data_file((int)hdr->th_stuff, O_WRONLY)) < 0) {
		tftpd_send_error(s,reply,TFTP_ENOTFOUND,from_addr, from_len);
		close(s);
		return;
	}

	ok = pdTRUE;
	closed = pdFALSE;
	block = 0;
	while (ok) {
		// Send ACK telling client he can send data
		reply->th_opcode = htons(ACK);
		reply->th_block = htons(block++); // postincrement
		for (tries = 0;  tries < TFTP_RETRIES_MAX;  tries++) {
			sendto(s, reply, 4, 0, (struct sockaddr *)from_addr, from_len);
			repeat_select:
			timeout.tv_sec = TFTP_TIMEOUT_PERIOD;
			timeout.tv_usec = 0;
			FD_ZERO(&fds);
			FD_SET(s, &fds);
			//vParTestToggleLED( TFTP_LED );
			if (lwip_select(s+1, &fds, 0, 0, &timeout) <= 0) {
				if (++total_timeouts > TFTP_TIMEOUT_MAX) {
					tftpd_send_error(s,reply,TFTP_EBADOP,from_addr, from_len);
					ok = pdFALSE;
					break;
				}
				continue; // retry the send, using up one retry.
			}
			//vParTestToggleLED( TFTP_LED );
			// Some data has arrived
			data_len = sizeof(data_in);
			client_len = sizeof(client_addr);
			if ((data_len = recvfrom(s, data_in, data_len, 0,
					(struct sockaddr *)&client_addr, &client_len)) < 0) {
				// What happened?  No data here!
				continue; // retry the send, using up one retry.
			}
			if (ntohs(response->th_opcode) == DATA &&
					ntohs(response->th_block) < block) {
				// Then it is repeat DATA with an old block; listen again,
				// but do not repeat sending the current ack, and do not
				// use up a retry count.  (we do re-send the ack if
				// subsequently we time out)
				goto repeat_select;
			}
			if (ntohs(response->th_opcode) == DATA &&
					ntohs(response->th_block) == block) {
				// Good data - write to file
				len = tftpd_write_data_file(fd, response->th_data, data_len-4);
				if (len < (data_len-4)) {
					// File is "full"
					tftpd_send_error(s,reply,TFTP_ENOSPACE,
							from_addr, from_len);
					ok = pdFALSE;  // Give up
					break; // out of the retries loop
				}
				if (data_len < (SEGSIZE+4)) {
					// End of file
					closed = pdTRUE;
					ok = pdFALSE;
					vParTestSetLED( 0 , 0 );

					if (tftpd_close_data_file(fd) == -1) {
						tftpd_send_error(s,reply,TFTP_EACCESS,
								from_addr, from_len);

						break;  // out of the retries loop
					}
					// Exception to the loop structure: we must ACK the last
					// packet, the one that implied EOF:
					reply->th_opcode = htons(ACK);
					reply->th_block = htons(block++); // postincrement
					sendto(s, reply, 4, 0, (struct sockaddr *)from_addr, from_len);
					break; // out of the retries loop
				}
				// Happy!  Break out of the retries loop.
				break;
			}
		} // End of the retries loop.
		if (TFTP_RETRIES_MAX <= tries) {
			tftpd_send_error(s,reply,TFTP_EBADOP,from_addr, from_len);
			ok = pdFALSE;
		}
	}
	close(s);
	if (!closed) {
		tftpd_close_data_file(fd);
	}
}


//
// Send a file to the client
//
static void
tftpd_read_file(struct tftphdr *hdr,
		struct sockaddr_in *from_addr, int from_len)
{
	struct tftphdr *reply = (struct tftphdr *)data_out;
	struct tftphdr *response = (struct tftphdr *)data_in;
	int fd, len, tries, ok, data_len, s;
	unsigned short block;
	struct timeval timeout;
	fd_set fds;
	int total_timeouts = 0;
	struct sockaddr_in client_addr, local_addr;
	int client_len;

	s = socket(AF_INET, SOCK_DGRAM, 0);
	if (s < 0) {
		return;
	}
	memset((char *)&local_addr, 0, sizeof(local_addr));
	local_addr.sin_family = AF_INET;
	local_addr.sin_len = sizeof(local_addr);
	local_addr.sin_addr.s_addr = htonl(INADDR_ANY);
	local_addr.sin_port = htons(INADDR_ANY);
	if (bind(s, (struct sockaddr *)&local_addr, sizeof(local_addr)) < 0) {
		// Problem setting up my end
		close(s);
		return;
	}
	if ((fd = tftpd_open_data_file((int)hdr->th_stuff, O_RDONLY)) < 0) {
		tftpd_send_error(s,reply,TFTP_ENOTFOUND,from_addr, from_len);
		close(s);
		return;
	}
	block = 0;
	ok = pdTRUE;
	while (ok) {
		// Read next chunk of file
		len = tftpd_read_data_file(fd, reply->th_data, SEGSIZE);
		reply->th_block = htons(++block); // preincrement
		reply->th_opcode = htons(DATA);
		for (tries = 0;  tries < TFTP_RETRIES_MAX;  tries++) {
			if (sendto(s, reply, 4+len, 0,
					(struct sockaddr *)from_addr, from_len) < 0) {
				// Something went wrong with the network!
				ok = pdFALSE;
				break;
			}
			repeat_select:
			timeout.tv_sec = TFTP_TIMEOUT_PERIOD;
			timeout.tv_usec = 0;
			FD_ZERO(&fds);
			FD_SET(s, &fds);
			//vParTestToggleLED( TFTP_LED );
			if (select(s+1, &fds, 0, 0, &timeout) <= 0) {
				if (++total_timeouts > TFTP_TIMEOUT_MAX) {
					tftpd_send_error(s,reply,TFTP_EBADOP,from_addr, from_len);
					ok = pdFALSE;
					break;
				}
				continue; // retry the send, using up one retry.
			}
			//vParTestToggleLED( TFTP_LED );
			data_len = sizeof(data_in);
			client_len = sizeof(client_addr);
			if ((data_len = recvfrom(s, data_in, data_len, 0,
					(struct sockaddr *)&client_addr,
					&client_len)) < 0) {
				// What happened?  Maybe someone lied to us...
				continue; // retry the send, using up one retry.
			}
			if ((ntohs(response->th_opcode) == ACK) &&
					(ntohs(response->th_block) < block)) {
				// Then it is a repeat ACK for an old block; listen again,
				// but do not repeat sending the current block, and do not
				// use up a retry count.  (we do re-send the data if
				// subsequently we time out)
				goto repeat_select;
			}
			if ((ntohs(response->th_opcode) == ACK) &&
					(ntohs(response->th_block) == block)) {
				// Happy!  Break out of the retries loop.
				break;
			}
		} // End of the retries loop.
		if (TFTP_RETRIES_MAX <= tries) {
			tftpd_send_error(s,reply,TFTP_EBADOP,from_addr, from_len);
			ok = pdFALSE;
		}
		if (len < SEGSIZE) {
			break; // That's end of file then.
		}
	}
	close(s);
	tftpd_close_data_file(fd);
}


portTASK_FUNCTION( vBasicTFTPServer, pvParameters ){

	//connectClient();

	int lSocket;
	struct sockaddr_in sLocalAddr;

	lSocket = lwip_socket(AF_INET, SOCK_STREAM, 0);
	if (lSocket < 0) return;

	memset((char *)&sLocalAddr, 0, sizeof(sLocalAddr));
	sLocalAddr.sin_family = AF_INET;
	sLocalAddr.sin_len = sizeof(sLocalAddr);
	sLocalAddr.sin_addr.s_addr = htonl(INADDR_ANY);
	sLocalAddr.sin_port = 5436;

	if (lwip_bind(lSocket, (struct sockaddr *)&sLocalAddr, sizeof(sLocalAddr)) < 0) {
		lwip_close(lSocket);
		return;
	}

	if ( lwip_listen(lSocket, 20) != 0 ){
		lwip_close(lSocket);
		return;
	}


	struct sockaddr_in client_addr;
	int addrlen=sizeof(client_addr);

	//usart_putchar(DBG_USART,'s' );

	clientfd = lwip_accept(lSocket, (struct sockaddr*)&client_addr, (socklen_t)&addrlen);


	if (clientfd>0){
		while (1) {

			int serialReading = 0;
			char buffer[1024];
			char pcReceived[20];
			int nbytes;
			int new_bytes;
			char address[2];
			char mode[3];
			char data [1024];
			int c;

			int timeout =0;
			int timeout1 =0;


			/*while(usart_test_hit(DBG_USART))    // Something on USART ?
			{

				if( stringPlace < 1000 && USART_SUCCESS==usart_read_char(DBG_USART, &c) )
				{
					serialRead[stringPlace] = c;
					stringPlace++;
					usart_putchar(DBG_USART,c );
				}
				else {
					usart_reset_status( DBG_USART );
				}
			}*/


			serialloop:
			while(timeout1 < 1000 )
			{
				while(usart_test_hit(DBG_USART))    // Something on USART ?
				{
					//if(started == 0) {sendUSBString("@");	started = 1;}//indicate to C-api that file is starting

					if(USART_SUCCESS==usart_read_char(DBG_USART, &c) )
					{
						//if(c=='&') {	end=1; break;}
						//usart_putchar(DBG_USART,c );
						serialRead[stringPlace] = c;
						stringPlace++;


						timeout1 = 0;
						timeout =0;
					}
					else
					{
						usart_reset_status( DBG_USART );
					}

					if (stringPlace ==1000 )
					{
						serialRead[stringPlace] = '@';
						serialRead[stringPlace+1]='\0';

						//serialRead[stringPlace]='\0';
						lwip_send(clientfd, serialRead,stringPlace+1, 0);

						stringPlace =0;

						//memset(serialRead, '\0', 10);
					}
				}
				if (serialReading == 0)
				{
					timeout1 = 0;
					timeout =0;
					goto here;
				}
				timeout ++;
				if (timeout % 10000 == 0)
				{
					timeout1++;
					timeout =0;

				}

			}

			usart_putchar(DBG_USART,'N' );
			usart_putchar(DBG_USART,'O' );
			usart_putchar(DBG_USART,'W' );
			usart_putchar(DBG_USART,'*' );
			usart_putchar(DBG_USART,'*' );
			usart_putchar(DBG_USART,'*' );
			usart_putchar(DBG_USART,'*' );
			usart_putchar(DBG_USART,'*' );
			usart_putchar(DBG_USART,'*' );
			usart_putchar(DBG_USART,'*' );
			usart_putchar(DBG_USART,'*' );
			usart_putchar(DBG_USART,'*' );
			usart_putchar(DBG_USART,'*' );
			usart_putchar(DBG_USART,'*' );
			usart_putchar(DBG_USART,'*' );
			usart_putchar(DBG_USART,'*' );


			serialRead[stringPlace] = '*';
			serialRead[stringPlace] = '\0';
			strcpy(buffer,serialRead);
			new_bytes = strlen(buffer);
			buffer[new_bytes]='\0';
			if (new_bytes>0 )
			{

				lwip_send(clientfd, buffer,new_bytes, 0);
			}

			stringPlace =0;
			memset(serialRead, '\0', 1024);
			serialReading = 0;

			here:
			nbytes=lwip_recv(clientfd, buffer, sizeof(buffer),0);
			if (nbytes >0)
			{
				pcReceived[0]= buffer[0];
				pcReceived[1]= buffer[1];
				pcReceived[2]= buffer[2];
				pcReceived[3]= buffer[3];
				pcReceived[4]= '\0';


				if(strcmp(pcReceived,"INTG") == 0)
				{
					strcpy(buffer,"INIT GPIB HAS BEEN RECEIVED\n");

					init_GPIB();
					strcat(buffer,"GPIB HAS BEEN INITIALIZED\n");

					new_bytes = sizeof(buffer);
					buffer[new_bytes]='\0';
					if (new_bytes>0) lwip_send(clientfd, buffer, new_bytes, 0);

				}

				else if(strcmp(pcReceived,"INTP") == 0)
				{

					//dummyFunction();
					strcpy(buffer,"INIT PARALLEL HAS BEEN RECEIVED");
					new_bytes = sizeof(buffer);
					buffer[new_bytes]='\0';

					if (new_bytes>0) lwip_send(clientfd, buffer, new_bytes, 0);
				}
				else if(strcmp(pcReceived,"INTS") == 0)
				{
					strcpy(buffer,"INIT Serial HAS BEEN RECEIVED@");
					new_bytes = sizeof(buffer);
					buffer[new_bytes]='\0';

					if (new_bytes>0) lwip_send(clientfd, buffer, new_bytes, 0);
				}
				else if(strcmp(pcReceived,"GPIB") == 0)
				{
					address[0]=buffer[4];
					address[1]= buffer[5];
					mode[0] = buffer[6];
					mode[1]='\0';
					if (strcmp(mode,"R") == 0)
					{

						if (readGPIB(address) == 0 )
						{
							strcpy(buffer,"GPIB data has been received");
							new_bytes = sizeof(buffer);
							if (new_bytes>0) lwip_send(clientfd, buffer, new_bytes, 0);
						}
						else
						{
							strcpy(buffer,"GPIB data problem");
							new_bytes = sizeof(buffer);
							if (new_bytes>0) lwip_send(clientfd, buffer, new_bytes, 0);
						}


					}
					else if (strcmp(mode,"F") == 0)
					{

						if(readGPIBWF(address) == 0)
						{
							strcpy(buffer,"GPIB data received done");
							new_bytes = sizeof(buffer);
							if (new_bytes>0) lwip_send(clientfd, buffer, new_bytes, 0);
						}

						else
						{
							strcpy(buffer,"GPIB data not correctly received");
							new_bytes = sizeof(buffer);
							if (new_bytes>0) lwip_send(clientfd, buffer, new_bytes, 0);
						}



					}
					else if (strcmp(mode,"W") == 0)
					{

						//lwip_close(clientfd);
						if (sendGPIBData(address, buffer, nbytes)!= 0)
						{
							strcpy(buffer,"GPIB write command is not successful");
							new_bytes = sizeof(buffer);
							buffer[new_bytes]='\0';
						}
						else
						{
							usart_putchar(DBG_USART,'w' );
							usart_putchar(DBG_USART,'r' );
							usart_putchar(DBG_USART,'i' );
							usart_putchar(DBG_USART,'t' );
							usart_putchar(DBG_USART,'e' );
							strcpy(buffer,"GPIB write command is successful");
							new_bytes = sizeof(buffer);
							buffer[new_bytes]='\0';
						}
						if (new_bytes>0 )
						{
							lwip_send(clientfd, buffer, new_bytes, 0);
						}
					}
					else
					{
						strcpy(buffer,"GPIB none matching mode has BEEN RECEIVED");
						new_bytes = sizeof(buffer);
						buffer[new_bytes]='\0';
						if (new_bytes>0 )
						{
							lwip_send(clientfd, buffer, new_bytes, 0);
						}
					}


				}
				else if(strcmp(pcReceived,"PARL") == 0)
				{

					mode[0] = buffer[4];
					mode[1]='\0';
					if (strcmp(mode,"R") == 0)
					{
						readParallel();
						strcpy(buffer,"Parallel read command");
						new_bytes = sizeof(buffer);
						buffer[new_bytes]='\0';
						if (new_bytes>0 )
						{
							lwip_send(clientfd, buffer, new_bytes, 0);
						}
					}
					else if (strcmp(mode,"W") == 0)
					{

						setupParallelWrite();
						usb2par(buffer, nbytes);		//writes until '/r'

						strcpy(buffer,"PARALLEL write command");
						new_bytes = sizeof(buffer);
						buffer[new_bytes]='\0';

						if (new_bytes>0 )
						{
							lwip_send(clientfd, buffer, new_bytes, 0);
						}
					}
					else if (strcmp(mode,"F") == 0)
					{

						usb2par(buffer, nbytes);		//writes until '/r'

						strcpy(buffer,"PARALLEL write command");
						new_bytes = sizeof(buffer);
						buffer[new_bytes]='\0';

						if (new_bytes>0 )
						{
							lwip_send(clientfd, buffer, new_bytes, 0);
						}
					}
					else
					{
						strcpy(buffer,"Parallel none matching mode has BEEN RECEIVED");
						new_bytes = sizeof(buffer);
						buffer[new_bytes]='\0';
					}


				}
				else if(strcmp(pcReceived,"SERL") == 0)
				{
					//usart_putchar(DBG_USART,'*' );
					int timeout =0;
					int timeout1 =0;
					mode[0] = buffer[4];
					mode[1] ='\0';
					serialReading = 1;
					if (strcmp(mode,"R") == 0)
					{


						goto serialloop;

					}
					else if (strcmp(mode,"W") == 0)
					{

						buffer[nbytes]='\n';
						buffer[nbytes+1]='\0';
						int ret = usb2ser(buffer, nbytes+1);

						strcpy(buffer,"Serial write command");
						new_bytes = sizeof(buffer);
						buffer[new_bytes]='\0';

						if (new_bytes>0 )
						{
							lwip_send(clientfd, buffer, new_bytes, 0);
						}
					}
					else if (strcmp(mode,"F") == 0)
					{
						// wait for the client to get stuff

						while(1){
							clientfd = lwip_accept(lSocket, (struct sockaddr*)&client_addr, (socklen_t)&addrlen);
							if (clientfd>0){
								do{
									nbytes=lwip_recv(clientfd, buffer, sizeof(buffer),0);
									buffer[nbytes]='\n';
									buffer[nbytes+1]='\0';
									int ret = usb2ser(buffer, nbytes+1);
									if (nbytes>0) lwip_send(clientfd, buffer, nbytes, 0);
								}  while (nbytes>0);

								lwip_close(clientfd);
							}

							// return what you have received
							strcpy(buffer,"Serial write command");
							new_bytes = sizeof(buffer);
							buffer[new_bytes]='\0';
						}




					}
					else
					{
						strcpy(buffer,"Serial none matching mode has BEEN RECEIVED");
						new_bytes = sizeof(buffer);
						buffer[new_bytes]='\0';

						if (new_bytes>0 )
						{
							lwip_send(clientfd, buffer, new_bytes, 0);
						}
					}


				}
				else
				{
					//strcpy(buffer,"Nothing HAS BEEN RECEIVED");
					new_bytes = sizeof(buffer);
					//buffer[new_bytes+1]='\0';

					if (new_bytes>0 )
					{
						lwip_send(clientfd, buffer, new_bytes, 0);
					}

				}



			}
		}

	}
	lwip_close(clientfd);
	lwip_close(lSocket);
}

int bin2dec(char *bin)

{

	int b, k, m, n;

	int len, sum = 0;

	len = strlen(bin) - 1;

	for(k = 0; k <= len; k++)

	{

		n = (bin[k] - '0'); // char to numeric value

		if ((n > 1) || (n < 0))

		{

			//puts("\n\n ERROR! BINARY has only 1 and 0!\n");

			return (0);

		}

		for(b = 1, m = len; m > k; m--)

		{

			// 1 2 4 8 16 32 64 ... place-values, reversed here

			b *= 2;

		}

		// sum it up

		sum = sum + n * b;

		//printf("%d*%d + ",n,b); // uncomment to show the way this works

	}

	return(sum);

}
void init_GPIB()
{
	enablePins();

	//set pin directions
	gpio_enable_pin_open_drain(SRQ);
	gpio_enable_pin_open_drain(NRFD);
	gpio_enable_pin_open_drain(NDAC);
	gpio_clr_gpio_pin(REN);
	gpio_clr_gpio_pin(ATN);
	gpio_set_gpio_pin(DAV);
	gpio_set_gpio_pin(EOI);
	gpio_set_gpio_pin(IFC);
	gpio_set_gpio_pin(TE);
	//gpio_clr_gpio_pin(DC);
	usart_putchar(DBG_USART,'G');
	usart_putchar(DBG_USART,'P');
	usart_putchar(DBG_USART,'I');
	usart_putchar(DBG_USART,'B');



}

char * itoa(int value, char *string, int radix)
{
	char tmp[33];
	char *tp = tmp;
	int i;
	unsigned v;
	int sign;
	char *sp;


	sign = (radix == 10 && value < 0);
	if (sign)
		v = -value;
	else
		v = (unsigned)value;
	while (v || tp == tmp)
	{
		i = v % radix;
		v = v / radix;
		if (i < 10)
			*tp++ = i+'0';
		else
			*tp++ = i + 'a' - 10;
	}

	if (string == 0)
		string = (char *)malloc((tp-tmp)+sign+1);
	sp = string;

	if (sign)
		*sp++ = '-';
	while (tp > tmp)
		*sp++ = *--tp;
	*sp = 0;
	return string;
}

void enablePins()
{
	gpio_enable_gpio_pin(SRQ);
	gpio_enable_gpio_pin(EOI);
	gpio_enable_gpio_pin(DAV);
	gpio_enable_gpio_pin(NRFD);
	gpio_enable_gpio_pin(NDAC);
	gpio_enable_gpio_pin(IFC);
	gpio_enable_gpio_pin(ATN);
	gpio_enable_gpio_pin(REN);
	gpio_enable_gpio_pin(DC);
	gpio_clr_gpio_pin(DC);
	gpio_enable_gpio_pin(TE);


	gpio_enable_gpio_pin(DATA1);
	gpio_enable_gpio_pin(DATA2);
	gpio_enable_gpio_pin(DATA3);
	gpio_enable_gpio_pin(DATA4);
	gpio_enable_gpio_pin(DATA5);
	gpio_enable_gpio_pin(DATA6);
	gpio_enable_gpio_pin(DATA7);
	gpio_enable_gpio_pin(DATA8);
}



char *chartobin ( unsigned char c )
{

	char bin[8] = {0};
	int i;

	for ( i = 6; i >= 0; i-- )
	{
		bin[i] = (c % 2) + '0';
		c /= 2;
	}
	return bin;
}


char binaryToAscii(int buffer[])
{
	char iVal={0};
	int i;
	for (i = 0 ; i < 7 ; i++ )
	{
		iVal = (iVal << 1) + (buffer[i] & 1);
	}
	return iVal;
}

int* createDataChar()
{
	static int buffer[7]={0};
	int i = 0;
	for(i=0;i<=6;i++){
		buffer[i]=0;
	}
	if (gpio_get_pin_value(DATA1))
	{
		buffer[6] = '0';
	}

	else if (!gpio_get_pin_value(DATA1))
	{

		buffer[6] = '1';
	}

	if (gpio_get_pin_value(DATA2))
	{
		buffer[5] = '0';
	}
	else if (!gpio_get_pin_value(DATA2))
	{

		buffer[5] = '1';
	}

	if (gpio_get_pin_value(DATA3))
	{
		buffer[4] = '0';
	}
	else if (!gpio_get_pin_value(DATA3))
	{

		buffer[4] = '1';
	}

	if (gpio_get_pin_value(DATA4))
	{
		buffer[3] = '0';
	}
	else if (!gpio_get_pin_value(DATA4))
	{
		buffer[3] = '1';
	}

	if (gpio_get_pin_value(DATA5))
	{
		buffer[2] = '0';
	}
	else if (!gpio_get_pin_value(DATA5))
	{

		buffer[2] = '1';
	}

	if (gpio_get_pin_value(DATA6))
	{
		buffer[1] = '0';
	}
	else if (!gpio_get_pin_value(DATA6))
	{
		buffer[1] = '1';
	}

	if (gpio_get_pin_value(DATA7))
	{
		buffer[0] = '0';
	}
	else if (!gpio_get_pin_value(DATA7))
	{

		buffer[0] = '1';
	}

	return buffer;
}


void SetDataLines(char controls[])
{
	if(controls[7] == '0')
		gpio_clr_gpio_pin(DATA1);
	else if(controls[7] == '1')
		gpio_set_gpio_pin(DATA1);

	if(controls[6] == '0')
		gpio_clr_gpio_pin(DATA2);
	else if(controls[6] == '1')
		gpio_set_gpio_pin(DATA2);

	if(controls[5] == '0')
		gpio_clr_gpio_pin(DATA3);
	else if(controls[5] == '1')
		gpio_set_gpio_pin(DATA3);

	if(controls[4] == '0')
		gpio_clr_gpio_pin(DATA4);
	else if(controls[4] == '1')
		gpio_set_gpio_pin(DATA4);

	if(controls[3] == '0')
		gpio_clr_gpio_pin(DATA5);
	else if(controls[3] == '1')
		gpio_set_gpio_pin(DATA5);

	if(controls[2] == '0')
		gpio_clr_gpio_pin(DATA6);
	else if(controls[2] == '1')
		gpio_set_gpio_pin(DATA6);

	if(controls[1] == '0')
		gpio_clr_gpio_pin(DATA7);
	else if(controls[1] == '1')
		gpio_set_gpio_pin(DATA7);

	if(controls[0] == '0')
		gpio_clr_gpio_pin(DATA8);
	else if(controls[0] == '1')
		gpio_set_gpio_pin(DATA8);
}

void SetControlLines(char controls[])
{
	if(controls[7] == '0')
		gpio_clr_gpio_pin(REN);
	else if(controls[7] == '1')
		gpio_set_gpio_pin(REN);

	if(controls[6] == '0')
		gpio_clr_gpio_pin(IFC);
	else if(controls[6] == '1')
		gpio_set_gpio_pin(IFC);

	if(controls[5] == '0')
		gpio_clr_gpio_pin(NDAC);
	else if(controls[5] == '1')
		gpio_set_gpio_pin(NDAC);

	if(controls[4] == '0')
		gpio_clr_gpio_pin(NRFD);
	else if(controls[4] == '1')
		gpio_set_gpio_pin(NRFD);

	if(controls[3] == '0')
		gpio_clr_gpio_pin(DAV);
	else if(controls[3] == '1')
		gpio_set_gpio_pin(DAV);

	if(controls[2] == '0')
		gpio_clr_gpio_pin(EOI);
	else if(controls[2] == '1')
		gpio_set_gpio_pin(EOI);

	if(controls[1] == '0')
		gpio_clr_gpio_pin(ATN);
	else if(controls[1] == '1')
		gpio_set_gpio_pin(ATN);

	if(controls[0] == '0')
		gpio_clr_gpio_pin(SRQ);
	else if(controls[0] == '1')
		gpio_set_gpio_pin(SRQ);
}

void setPinsDependingOnData(char c)
{
	char *binary;
	binary = chartobin (  c );

	if (binary[7] == '1')
		gpio_clr_gpio_pin(DATA1);
	else if (binary[7] == '0')
		gpio_set_gpio_pin(DATA1);

	if (binary[6] == '1')
		gpio_clr_gpio_pin(DATA2);
	else if (binary[6] == '0')
		gpio_set_gpio_pin(DATA2);

	if (binary[5] == '1')
		gpio_clr_gpio_pin(DATA3);
	else if (binary[5] == '0')
		gpio_set_gpio_pin(DATA3);

	if (binary[4] == '1')
		gpio_clr_gpio_pin(DATA4);
	else if (binary[4] == '0')
		gpio_set_gpio_pin(DATA4);

	if (binary[3] == '1')
		gpio_clr_gpio_pin(DATA5);
	else if (binary[3] == '0')
		gpio_set_gpio_pin(DATA5);

	if (binary[2] == '1')
		gpio_clr_gpio_pin(DATA6);
	else if (binary[2] == '0')
		gpio_set_gpio_pin(DATA6);

	if (binary[1] == '1')
		gpio_clr_gpio_pin(DATA7);
	else if (binary[1] == '0')
		gpio_set_gpio_pin(DATA7);

	if (binary[0] == '1')
		gpio_clr_gpio_pin(DATA8);
	else if (binary[0] == '0')
		gpio_set_gpio_pin(DATA8);

	return;
}

void SetListenerTalker(char c)
{
	gpio_clr_gpio_pin(ATN);
		setPinsDependingOnData(c);
		while (gpio_get_pin_value(NDAC) && gpio_get_pin_value(NRFD)){
			//sendUSBString("in the loop1 set listener talker&");
		}
		while(!gpio_get_pin_value(NRFD)){
			//sendUSBString("in the loop2 set listener talker&");
		}
		gpio_clr_gpio_pin(DAV);
		while(!gpio_get_pin_value(NDAC)){
			//sendUSBString("in the loop3 set listener talker&");
		}
		gpio_set_gpio_pin(DAV);
}

// will have to invert the string



int sendGPIBData(char *add, char *data, int size)
{
	//prepare pins for write
	gpio_enable_gpio_pin(NRFD);
	gpio_enable_gpio_pin(EOI);
	gpio_enable_gpio_pin(NDAC);
	gpio_enable_gpio_pin(DAV);
	gpio_enable_gpio_pin(ATN);
	gpio_enable_pin_open_drain(SRQ);
	gpio_enable_pin_open_drain(NRFD);
	gpio_enable_pin_open_drain(NDAC);
	gpio_clr_gpio_pin(REN);
	gpio_clr_gpio_pin(ATN);
	gpio_set_gpio_pin(DAV);
	gpio_set_gpio_pin(EOI);
	gpio_set_gpio_pin(IFC);
	gpio_set_gpio_pin(TE);
	//gpio_clr_gpio_pin(DC);

	//expects PC to send numAddresses, space, 2 char addresses (no spaces), dataLength, space, data
	//int numAddresses, dataLength, i, address;
	char c;

	//TODO: for setlistenertalker and the send data code, put limits on while loop and return error code int
	//numAddresses = getPcInt();

	SetListenerTalker('_');	  //Untalk

	SetListenerTalker('?');	  //Unlisten

	SetListenerTalker('@');  // for talker :(hex) 40 + address of controller) in this case (hex)40 + 0 is @ in ascii


	int	address = (add[0] -48)*10 +  (add[1] -48);	//convert two ascii chars to a two digit integer address
	SetListenerTalker(32+address); //for listener :(hex) 20 + address of the instrument)


	//send data
	//dataLength = getPcInt();
	int i;
	size = strlen(data);
	for(i=7; i<size-1; i++)
	{
		//sendUSBString("ent");
		c= data[i];
		usart_putchar(DBG_USART,c);
		//uart_usb_flush();
		//sendUSBString("sending");
		gpio_set_gpio_pin(ATN);
		setPinsDependingOnData(c);
		while (gpio_get_pin_value(NDAC) && gpio_get_pin_value(NRFD)){
			usart_putchar(DBG_USART,'A');
		}
		while(!gpio_get_pin_value(NRFD)){
			usart_putchar(DBG_USART,'B');
		}
		gpio_clr_gpio_pin(DAV);
		while(!gpio_get_pin_value(NDAC)){
			usart_putchar(DBG_USART,'C');
		}
		gpio_set_gpio_pin(DAV);
	}
	usart_putchar(DBG_USART,'(');
	gpio_clr_gpio_pin(EOI);
	c= data[size];
	usart_putchar(DBG_USART,c);

	setPinsDependingOnData(c);
	while (gpio_get_pin_value(NDAC) && gpio_get_pin_value(NRFD)){	}
	while(!gpio_get_pin_value(NRFD)){	}
	gpio_clr_gpio_pin(DAV);
	while(!gpio_get_pin_value(NDAC)){	}
	gpio_set_gpio_pin(DAV);
	gpio_set_gpio_pin(EOI);
	usart_putchar(DBG_USART,'e');
	return 0;
}

int usb2ser(char *data, int length)
{
	char c;
	//if (usart_tx_ready(DBG_USART)) // USART free ?
	{
		//usart_putchar(DBG_USART,'\r');
		//usart_putchar(DBG_USART,'\n');
		int i;
		length = strlen(data);
		for (i =5;i<length;i++)
		{
			c= data[i];
			/*if( c=='\n' )	//finish when receive carriage return
			{
				usart_putchar(DBG_USART,'\r');
				return 0;
			}*/

			usart_putchar(DBG_USART,c);
		}
	}
	return 0;
}

int dummyFunction()
{
	int timeout =0;
	int timeout1 =0;

	gpio_enable_gpio_pin(nSTROBE);
		gpio_enable_pin_open_drain(nSTROBE);
		gpio_enable_gpio_pin(nACK);
		gpio_enable_pin_open_drain(nACK);
		gpio_enable_gpio_pin(BUSY);
		gpio_enable_pin_open_drain(BUSY);
		gpio_enable_gpio_pin(PAPEREND);
		gpio_enable_pin_open_drain(PAPEREND);
		gpio_enable_gpio_pin(SELECT);
		gpio_enable_pin_open_drain(SELECT);
		gpio_enable_gpio_pin(nAUTOLF);
		gpio_enable_pin_open_drain(nAUTOLF);
		gpio_enable_gpio_pin(nERROR);
		gpio_enable_pin_open_drain(nERROR);
		gpio_enable_gpio_pin(nINIT);
		gpio_enable_pin_open_drain(nINIT);
		gpio_enable_gpio_pin(nSELECTIN);
		gpio_enable_pin_open_drain(nSELECTIN);


		gpio_enable_gpio_pin(DATA1);
		gpio_enable_pin_open_drain(DATA1);
		gpio_enable_gpio_pin(DATA2);
		gpio_enable_pin_open_drain(DATA2);
		gpio_enable_gpio_pin(DATA3);
		gpio_enable_pin_open_drain(DATA3);
		gpio_enable_gpio_pin(DATA4);
		gpio_enable_pin_open_drain(DATA4);
		gpio_enable_gpio_pin(DATA5);
		gpio_enable_pin_open_drain(DATA5);
		gpio_enable_gpio_pin(DATA6);
		gpio_enable_pin_open_drain(DATA6);
		gpio_enable_gpio_pin(DATA7);
		gpio_enable_pin_open_drain(DATA7);
		gpio_enable_gpio_pin(DATA8);
		gpio_enable_pin_open_drain(DATA8);

	usart_putchar(DBG_USART,'h');
	usart_putchar(DBG_USART,'e');
	usart_putchar(DBG_USART,'l');
	usart_putchar(DBG_USART,'l');
	usart_putchar(DBG_USART,'o');
while(1)
{
	 readDataPins();
	 readControlPins();
	 while (timeout1 < 1000000)
	 		{
	 			timeout++;
	 			if (timeout == 100000)
	 			{
	 				timeout =0;
	 				timeout1++;
	 			}

	 		}
	 		timeout1 =0;

}
/*
	gpio_enable_gpio_pin(nSTROBE);
	gpio_set_gpio_pin(nSTROBE);
	gpio_enable_gpio_pin(nACK);
	gpio_set_gpio_pin(nACK);
	gpio_enable_gpio_pin(BUSY);
	gpio_set_gpio_pin(BUSY);
	gpio_enable_gpio_pin(PAPEREND);
	gpio_set_gpio_pin(PAPEREND);
	gpio_enable_gpio_pin(SELECT);
	gpio_set_gpio_pin(SELECT);
	gpio_enable_gpio_pin(nAUTOLF);
	gpio_set_gpio_pin(nAUTOLF);
	gpio_enable_gpio_pin(nERROR);
	gpio_set_gpio_pin(nERROR);
	gpio_enable_gpio_pin(nINIT);
	gpio_set_gpio_pin(nINIT);
	gpio_enable_gpio_pin(nSELECTIN);
	gpio_set_gpio_pin(nSELECTIN);


	gpio_enable_gpio_pin(DATA1);
	gpio_set_gpio_pin(DATA1);
	gpio_enable_gpio_pin(DATA2);
	gpio_clr_gpio_pin(DATA2);
	gpio_enable_gpio_pin(DATA3);
	gpio_set_gpio_pin(DATA3);
	gpio_enable_gpio_pin(DATA4);
	gpio_clr_gpio_pin(DATA4);
	gpio_enable_gpio_pin(DATA5);
	gpio_set_gpio_pin(DATA5);
	gpio_enable_gpio_pin(DATA6);
	gpio_clr_gpio_pin(DATA6);
	gpio_enable_gpio_pin(DATA7);
	gpio_set_gpio_pin(DATA7);
	gpio_enable_gpio_pin(DATA8);
	gpio_clr_gpio_pin(DATA8);

*/



	return 0;
}

int setListTalker()
{
	SetListenerTalker('_');
	SetListenerTalker('@');
	SetListenerTalker('?');
	SetListenerTalker('!');


	usart_putchar(DBG_USART,'S');
	usart_putchar(DBG_USART,'E');
	usart_putchar(DBG_USART,'N');
	usart_putchar(DBG_USART,'D');
	usart_putchar(DBG_USART,'C');
	usart_putchar(DBG_USART,'O');
	usart_putchar(DBG_USART,'M');
	usart_putchar(DBG_USART,'M');
	usart_putchar(DBG_USART,'A');
	usart_putchar(DBG_USART,'N');
	usart_putchar(DBG_USART,'D');
	return 0;
}


void resetBus()
{
	enablePins();
	gpio_enable_gpio_pin(NRFD);
	gpio_enable_gpio_pin(EOI);
	gpio_enable_gpio_pin(NDAC);
	gpio_enable_gpio_pin(DAV);
	gpio_enable_gpio_pin(ATN);

	//SetTalk
	//SetControlLines("01000011");        //DDRComm
	//SetControlLines("01110011");        //DDRTALK
	gpio_enable_pin_open_drain(SRQ);
	gpio_enable_pin_open_drain(NRFD);
	gpio_enable_pin_open_drain(NDAC);
	gpio_clr_gpio_pin(REN);
	gpio_clr_gpio_pin(ATN);
	gpio_set_gpio_pin(DAV);
	gpio_set_gpio_pin(EOI);


	//delay at least 100ms for IFC
	//delay_ms1(1);

	gpio_set_gpio_pin(IFC);

	//ADDED
	gpio_set_gpio_pin(TE);
	//gpio_clr_gpio_pin(DC);

}


char* createDataChar2()
{
	static char buffer[9]={0};
	int i = 0;
	for(i=0;i<=7;i++){
		buffer[i]=0;
	}
	buffer[8] ='\0';
	if (gpio_get_pin_value(DATA1))
	{
		buffer[7] = '0';
	}

	else if (!gpio_get_pin_value(DATA1))
	{

		buffer[7] = '1';
	}

	if (gpio_get_pin_value(DATA2))
	{
		buffer[6] = '0';
	}
	else if (!gpio_get_pin_value(DATA2))
	{

		buffer[6] = '1';
	}

	if (gpio_get_pin_value(DATA3))
	{
		buffer[5] = '0';
	}
	else if (!gpio_get_pin_value(DATA3))
	{

		buffer[5] = '1';
	}

	if (gpio_get_pin_value(DATA4))
	{
		buffer[4] = '0';
	}
	else if (!gpio_get_pin_value(DATA4))
	{
		buffer[4] = '1';
	}

	if (gpio_get_pin_value(DATA5))
	{
		buffer[3] = '0';
	}
	else if (!gpio_get_pin_value(DATA5))
	{

		buffer[3] = '1';
	}

	if (gpio_get_pin_value(DATA6))
	{
		buffer[2] = '0';
	}
	else if (!gpio_get_pin_value(DATA6))
	{
		buffer[2] = '1';
	}

	if (gpio_get_pin_value(DATA7))
	{
		buffer[1] = '0';
	}
	else if (!gpio_get_pin_value(DATA7))
	{

		buffer[1] = '1';
	}
	if (gpio_get_pin_value(DATA8))
	{
		buffer[0] = '0';
	}
	else if (!gpio_get_pin_value(DATA8))
	{

		buffer[0] = '1';
	}

	return buffer;
}


void RcvBinData(){
	char temp;
	char buffer[1024];

	int stringPlace =0;


	//lwip_send(clientfd, buffer,stringPlace+1, 0);

	gpio_clr_gpio_pin(NDAC);
	gpio_set_gpio_pin(ATN);


	while(gpio_get_pin_value(EOI))
	{

		gpio_set_gpio_pin(NRFD);

		while(gpio_get_pin_value(DAV)){}


		temp = (binaryToAscii( createDataChar()));
		buffer[stringPlace] = temp;
		stringPlace++;

		if (stringPlace == 1020)
		{
			buffer[stringPlace] = '@';
			lwip_send(clientfd, buffer,stringPlace+1, 0);
			stringPlace =0;
			memset(buffer, '\0', 1024);
		}
		gpio_clr_gpio_pin(NRFD);  // Not ready for more data
		gpio_set_gpio_pin(NDAC);  // Data received

		while(! gpio_get_pin_value(DAV)){}
		gpio_clr_gpio_pin(NDAC);  // Data not accepted (no data on bus)

	}

	buffer[stringPlace] = '@';
	lwip_send(clientfd, buffer,stringPlace+1, 0);
	gpio_clr_gpio_pin(ATN);


} // RcvBinData



void  RcvWaveformDump(){

	char ethernet_buffer[1024];
	int stringPlace =0;

	char buffer[18];
	char *data1;
	char *data2;
	char data_out[10];
	char *char_ret;
	char *num_ret;
	char data_num[10];
	int first_character =1;
	int second_character =0;
	int continuing = 1;
	int num_times;
	int mul = 10;

	gpio_clr_gpio_pin(NDAC);
	gpio_set_gpio_pin(ATN);

	int k=0;
	int s =0;
	int i;
	int ret;
	int counter =0;
	int num_times_loop = 0;
	for(i=0;i<=16;i++){
		buffer[i]=0;
	}


	int timeout =0;
	int timeout1 =0;
	while (timeout1 < 100)
	{
		while(gpio_get_pin_value(EOI) && continuing)
		{
			timeout1 = 200;

			gpio_set_gpio_pin(NRFD);



			while(gpio_get_pin_value(DAV)){


			}
			if(first_character)
			{

				data1 =  createDataChar2();
				ret = bin2dec(data1);
				char_ret = itoa(ret, data_out, 10);
				for (k =0; k<strlen(char_ret);k++ )
				{

					//lwip_send(clientfd, ethernet_buffer,stringPlace+1, 0);
				}
				if (!(char_ret[0] =='3' && char_ret[1]=='5'))
				{
					//uart_usb_putchar('N');
					//uart_usb_putchar('O');
					//uart_usb_putchar('T');
					//uart_usb_putchar(' ');
					//uart_usb_putchar('#');
					//uart_usb_flush();

					return;
				}

				continuing = 1;
				first_character =0;
				second_character =1;

			}
			else if (second_character)
			{
				data1 =  createDataChar2();
				ret = bin2dec(data1);
				num_times = ret-48;
				char_ret = itoa(ret, data_out, 10);
				//uart_usb_putchar('T');
				//uart_usb_putchar('I');
				//uart_usb_putchar('M');
				//uart_usb_putchar('E');
				//uart_usb_putchar('S');

				//for (k =0; k<strlen(char_ret);k++ )
				//{
				//         uart_usb_putchar(char_ret[k]);
				// }
				//sendUSBString(char_ret);

				second_character =0;
			}
			else
			{
				counter++;
				mul = mul/10;

				if (counter ==1)
				{
					ret =0;
					mul =1000;
				}
				data1 =  createDataChar2();
				ret += mul*(bin2dec(data1)-48);

				//uart_usb_putchar('O');
				if (counter == num_times)
				{
					ret = ret/2;

					//uart_usb_putchar('E');
					//uart_usb_putchar('N');
					//        uart_usb_putchar('D');

					continuing =0;
					char_ret = itoa(ret, data_out, 10);
					//for (k =0; k<strlen(char_ret);k++ )
					///// {
					//         uart_usb_putchar(char_ret[k]);
					// }
					//sendUSBString(char_ret);
				}

			}


			gpio_clr_gpio_pin(NRFD);  // Not ready for more data
			gpio_set_gpio_pin(NDAC);  // Data received



			while(! gpio_get_pin_value(DAV))
			{

			}
			gpio_clr_gpio_pin(NDAC);  // Data not accepted (no data on bus)

		}
		timeout ++;
		if (timeout == 10)
		{
			timeout1++;
		}
	}


	//changed
	num_times_loop = ret;
	//while(gpio_get_pin_value(EOI))
	while (num_times_loop !=0)
	{

		num_times_loop --;

		gpio_set_gpio_pin(NRFD);



		while(gpio_get_pin_value(DAV)){


		}


		data1 =  createDataChar2();

		for (k =0; k<8;k++ )
		{
			//uart_usb_putchar(data1[k]);
			buffer[k+8]= data1[k];

		}

		//uart_usb_putchar(' ');

		// uart_usb_putchar(binaryToAscii( createDataChar()));
		//readDataPins();


		//uart_usb_flush();
		gpio_clr_gpio_pin(NRFD);  // Not ready for more data
		gpio_set_gpio_pin(NDAC);  // Data received



		while(! gpio_get_pin_value(DAV))
		{

		}
		gpio_clr_gpio_pin(NDAC);  // Data not accepted (no data on bus)





		// get the second byte


		gpio_set_gpio_pin(NRFD);



		while(gpio_get_pin_value(DAV)){


		}

		data2 =  createDataChar2();


		for (k =0; k<8;k++ )
		{

			buffer[k]= data2[k];
		}





		gpio_clr_gpio_pin(NRFD);  // Not ready for more data
		gpio_set_gpio_pin(NDAC);  // Data received



		while(! gpio_get_pin_value(DAV))
		{

		}
		gpio_clr_gpio_pin(NDAC);  // Data not accepted (no data on bus)



		ret = bin2dec(buffer);



		char_ret = itoa(ret, data_out, 10);

		for (k =0; k<strlen(char_ret);k++ )
		{
			//uart_usb_putchar(char_ret[k]);
			//uart_usb_flush();
			ethernet_buffer[stringPlace] = char_ret[k];
			stringPlace++;
			if (stringPlace == 1020)
			{
				ethernet_buffer[stringPlace] = '@';
				lwip_send(clientfd, ethernet_buffer,stringPlace+1, 0);
				stringPlace =0;
				memset(ethernet_buffer, '\0', 1024);
			}
		}



	}
	ethernet_buffer[stringPlace] = '@';
	lwip_send(clientfd, ethernet_buffer,stringPlace+1, 0);
	//uart_usb_flush();
	return ;

} // RcvBinData

void setPinsDependingOnDataParallel (char c)
{
	char *binary;
	binary = chartobin (  c );

	if (binary[7] == '0')
		gpio_clr_gpio_pin(DATA1);
	else if (binary[7] == '1')
		gpio_set_gpio_pin(DATA1);

	if (binary[6] == '0')
		gpio_clr_gpio_pin(DATA2);
	else if (binary[6] == '1')
		gpio_set_gpio_pin(DATA2);

	if (binary[5] == '0')
		gpio_clr_gpio_pin(DATA3);
	else if (binary[5] == '1')
		gpio_set_gpio_pin(DATA3);

	if (binary[4] == '0')
		gpio_clr_gpio_pin(DATA4);
	else if (binary[4] == '1')
		gpio_set_gpio_pin(DATA4);

	if (binary[3] == '0')
		gpio_clr_gpio_pin(DATA5);
	else if (binary[3] == '1')
		gpio_set_gpio_pin(DATA5);

	if (binary[2] == '0')
		gpio_clr_gpio_pin(DATA6);
	else if (binary[2] == '1')
		gpio_set_gpio_pin(DATA6);

	if (binary[1] == '0')
		gpio_clr_gpio_pin(DATA7);
	else if (binary[1] == '1')
		gpio_set_gpio_pin(DATA7);

	if (binary[0] == '0')
		gpio_clr_gpio_pin(DATA8);
	else if (binary[0] == '1')
		gpio_set_gpio_pin(DATA8);

	return;
}

int readGPIB(char *in_address)
{

int address;
//TODO: for setlistenertalker, put limits on while loop and return error code int
SetListenerTalker('?');  //Unlisten
SetListenerTalker(' '); // (for listener: (hex) 20 + address of controller) in this case 20+0
address = (in_address[0] -48)*10 +  (in_address[1] -48);
SetListenerTalker(64+address); //(for talker:(hex) 40 + address of the instrument) or decimal 64+address

//setup pins for reading
gpio_clr_gpio_pin(TE);
gpio_enable_gpio_pin(NRFD);
gpio_enable_gpio_pin(NDAC);
gpio_enable_pin_open_drain(DAV);
gpio_enable_pin_open_drain(EOI);
gpio_enable_gpio_pin(DATA1);
gpio_enable_gpio_pin(DATA2);
gpio_enable_gpio_pin(DATA3);
gpio_enable_gpio_pin(DATA4);
gpio_enable_gpio_pin(DATA5);
gpio_enable_gpio_pin(DATA6);
gpio_enable_gpio_pin(DATA7);
gpio_enable_gpio_pin(DATA8);

RcvBinData();

return 0;

}



int readGPIBWF(char *in_address)
{
	//expects PC to send a two char address followed by space


	int address;
	resetBus();
	//TODO: for setlistenertalker, put limits on while loop and return error code int
	SetListenerTalker('?');  //Unlisten
	SetListenerTalker(' '); // (for listener: (hex) 20 + address of controller) in this case 20+0
	address = (in_address[0] -48)*10 +  (in_address[1] -48);
	SetListenerTalker(64+address); //(for talker:(hex) 40 + address of the instrument) or decimal 64+address
	gpio_clr_gpio_pin(TE);
	//setup pins for reading
	gpio_enable_gpio_pin(NRFD);
	gpio_enable_gpio_pin(NDAC);
	gpio_enable_pin_open_drain(DAV);
	gpio_enable_pin_open_drain(EOI);
	gpio_enable_gpio_pin(DATA1);
	gpio_enable_gpio_pin(DATA2);
	gpio_enable_gpio_pin(DATA3);
	gpio_enable_gpio_pin(DATA4);
	gpio_enable_gpio_pin(DATA5);
	gpio_enable_gpio_pin(DATA6);
	gpio_enable_gpio_pin(DATA7);
	gpio_enable_gpio_pin(DATA8);

	RcvWaveformDump();
	resetBus();
	return 0;
}

char binaryToAsciiPar(int buffer[])
{

	char iVal={0};
	int i;
	for (i = 0 ; i < 8 ; i++ )
	{

		iVal = (iVal << 1) + (buffer[i] & 1);
	}

	return iVal;


}

int* createDataCharParallel()
{
	static int buffer[8]={0};
	int i = 0;
	for(i=0;i<=7;i++){
		buffer[i]=0;
	}
	if (gpio_get_pin_value(DATA1))
	{
		buffer[7] = '1';
	}

	else if (!gpio_get_pin_value(DATA1))
	{

		buffer[7] = '0';
	}

	if (gpio_get_pin_value(DATA2))
	{
		buffer[6] = '1';
	}

	else if (!gpio_get_pin_value(DATA2))
	{

		buffer[6] = '0';
	}

	if (gpio_get_pin_value(DATA3))
	{
		buffer[5] = '1';
	}
	else if (!gpio_get_pin_value(DATA3))
	{

		buffer[5] = '0';
	}

	if (gpio_get_pin_value(DATA4))
	{
		buffer[4] = '1';
	}
	else if (!gpio_get_pin_value(DATA4))
	{

		buffer[4] = '0';
	}

	if (gpio_get_pin_value(DATA5))
	{
		buffer[3] = '1';
	}
	else if (!gpio_get_pin_value(DATA5))
	{
		buffer[3] = '0';
	}

	if (gpio_get_pin_value(DATA6))
	{
		buffer[2] = '1';
	}
	else if (!gpio_get_pin_value(DATA6))
	{

		buffer[2] = '0';
	}

	if (gpio_get_pin_value(DATA7))
	{
		buffer[1] = '1';
	}
	else if (!gpio_get_pin_value(DATA7))
	{
		buffer[1] = '0';
	}

	if (gpio_get_pin_value(DATA8))
	{
		buffer[0] = '1';
	}
	else if (!gpio_get_pin_value(DATA8))
	{

		buffer[0] = '0';
	}

	return buffer;
}

void enableParallelPins()
{
	gpio_enable_gpio_pin(nSTROBE);
	gpio_enable_gpio_pin(nACK);
	gpio_enable_gpio_pin(BUSY);
	gpio_enable_gpio_pin(PAPEREND);
	gpio_enable_gpio_pin(SELECT);
	gpio_enable_gpio_pin(nAUTOLF);
	gpio_enable_gpio_pin(nERROR);
	gpio_enable_gpio_pin(nINIT);
	gpio_enable_gpio_pin(nSELECTIN);


	gpio_enable_gpio_pin(DATA1);
	gpio_enable_gpio_pin(DATA2);
	gpio_enable_gpio_pin(DATA3);
	gpio_enable_gpio_pin(DATA4);
	gpio_enable_gpio_pin(DATA5);
	gpio_enable_gpio_pin(DATA6);
	gpio_enable_gpio_pin(DATA7);
	gpio_enable_gpio_pin(DATA8);
}

void setupParallelRead()
{
	enableParallelPins();

	gpio_enable_pin_open_drain(nSTROBE);
	gpio_enable_pin_open_drain(DATA1);
	gpio_enable_pin_open_drain(DATA2);
	gpio_enable_pin_open_drain(DATA3);
	gpio_enable_pin_open_drain(DATA4);
	gpio_enable_pin_open_drain(DATA5);
	gpio_enable_pin_open_drain(DATA6);
	gpio_enable_pin_open_drain(DATA7);
	gpio_enable_pin_open_drain(DATA8);
	gpio_set_gpio_pin(BUSY);
	gpio_set_gpio_pin(nACK);
	gpio_set_gpio_pin(SELECT);
	gpio_clr_gpio_pin(PAPEREND);
}

void setupParallelWrite()
{
	enableParallelPins();

	gpio_enable_pin_open_drain(BUSY);
	gpio_enable_pin_open_drain(nACK);
	gpio_enable_pin_open_drain(SELECT);
	gpio_enable_pin_open_drain(PAPEREND);
}


void readParallel()
{
	char buffer[1024];
	int stringPlace =0;

	setupParallelRead();
	//gpio_clr_gpio_pin(BUSY);
	int timeout = 0;
	int timeout1 = 0;
	while(1){
		//clear busy to start receiving
		gpio_clr_gpio_pin(BUSY);


		//readControlPins();
		//wait for nStrobe with timeout
		while(gpio_get_pin_value(nSTROBE))
		{
			timeout++;
			if(timeout == 99999)
			{
				timeout = 0;
				timeout1++;
				if(timeout1 == 100)
					goto done;
			}
		}
		gpio_set_gpio_pin(BUSY);	//indicate busy to sender
		//readControlPins();
		//reset timeouts
		timeout = 0;
		timeout1= 0;
		buffer[stringPlace] = binaryToAsciiPar( createDataCharParallel());
		stringPlace++;

		if (stringPlace == 500)
		{
			buffer[stringPlace] = '@';
			lwip_send(clientfd, buffer,stringPlace+1, 0);
			stringPlace =0;
			//memset(buffer, '\0', 1024);
		}


	}
	done:

	buffer[stringPlace] = '@';
	lwip_send(clientfd, buffer,stringPlace+1, 0);
}


void usb2par(char *data, int length)
{
	int i;
	char c;
	int timeout =0;
	int timeout1 =0;

	length = strlen(data);
	for (i=5;i<length;i++)
	{

		c = data[i];

		usart_putchar(DBG_USART,c);
		while (timeout1 < 1000000)
		{
			timeout++;
			if (timeout == 100000)
			{
				timeout =0;
				timeout1++;
			}

		}
		timeout1 =0;
		//send char on the bus
		setPinsDependingOnDataParallel(c);

		//wait if peripheral is busy
		//while (gpio_get_pin_value(BUSY)) {}
		//strobe the nSTROBE line
		gpio_clr_gpio_pin(nSTROBE);
		gpio_set_gpio_pin(nSTROBE);

	}
}


int connectClient()
{

	//The port and address you want to connect to
	usart_putchar(DBG_USART,'r' );
	int host_port= 5438;
	char* host_name="192.168.0.3";


	//Initialize sockets and set any options

	int * p_int ;
	//int hsock = socket(AF_INET, SOCK_DGRAM, 0);
	int hsock = socket(AF_INET, SOCK_STREAM, 0);
	if(hsock < 0 ){
		usart_putchar(DBG_USART,'e' );
		usart_putchar(DBG_USART,'r' );
		usart_putchar(DBG_USART,'r' );
		usart_putchar(DBG_USART,'o' );
		usart_putchar(DBG_USART,'r' );
		//printf("Error initializing socket %d\n",WSAGetLastError());
		return -1;
	}

	/*
	p_int = (int*)malloc(sizeof(int));
	 *p_int = 1;
	if( (setsockopt(hsock, SOL_SOCKET, SO_REUSEADDR, (char*)p_int, sizeof(int)) == -1 )){
		//printf("Error setting options %d\n", WSAGetLastError());
		usart_putchar(DBG_USART,'e' );
		usart_putchar(DBG_USART,'r' );
		usart_putchar(DBG_USART,'r' );
		usart_putchar(DBG_USART,'o' );
		usart_putchar(DBG_USART,'r' );
		free(p_int);
		return -1;
	}
	free(p_int);*/

	//Connect to the server
	struct sockaddr_in my_addr;

	memset((char *)&my_addr, 0, sizeof(my_addr));

	my_addr.sin_family = AF_INET ;
	my_addr.sin_len = sizeof(my_addr);
	my_addr.sin_port = htons(host_port);
	memset(&(my_addr.sin_zero), 0, 8);
	my_addr.sin_addr.s_addr = inet_addr(host_name);;

	//usart_putchar(DBG_USART,'R' );
	//memset(&(my_addr.sin_zero), 0, 8);



	/*
	if (bind(hsock, (struct sockaddr *)&my_addr, sizeof(my_addr)) < 0) {
				// Problem setting up my end
				close(hsock);
				return -1;
			}
	 */

	if( lwip_connect( hsock, (struct sockaddr*)&my_addr, sizeof(my_addr)) == SO_ERROR){
		usart_putchar(DBG_USART,'e' );
		usart_putchar(DBG_USART,'r' );
		usart_putchar(DBG_USART,'r' );
		usart_putchar(DBG_USART,'o' );
		usart_putchar(DBG_USART,'r' );
		return -1;
	}



	/*
if (bind(hsock, (struct sockaddr *)&my_addr, sizeof(my_addr)) < 0) {
			// Problem setting up my end
			close(hsock);
			return -1;
		}*/

	//Now lets do the client related stuff

	while (1)
	{

		//usart_putchar(DBG_USART,'p' );

		char *buffer;
		buffer = (char*) malloc (1025);

		int buffer_len  = 1024;
		int bytecount;

		usart_putchar(DBG_USART,'s' );
		usart_putchar(DBG_USART,'e' );
		usart_putchar(DBG_USART,'n' );
		usart_putchar(DBG_USART,'t' );

		usart_putchar(DBG_USART,':' );

		strcpy(buffer,"hello");
		strcat(buffer,"\0");
		int j;
		for (j=0; j<6;j++)
		{
			usart_putchar(DBG_USART,buffer[j] );
		}


		bytecount = -1;

		while (bytecount <=0)
		{
			if ((bytecount=lwip_send(hsock, buffer, 6,0))==SO_ERROR){
				usart_putchar(DBG_USART,'e' );
				usart_putchar(DBG_USART,'r' );
				usart_putchar(DBG_USART,'r' );
				usart_putchar(DBG_USART,'o' );
				usart_putchar(DBG_USART,'r' );
				return -1;
			}

		}



		memset(buffer, '\0', buffer_len);
		bytecount = -1;

		while (bytecount <=0)
		{

			if((bytecount = lwip_recv(hsock, buffer, sizeof(buffer), 0))==SO_ERROR){
				usart_putchar(DBG_USART,'e' );
				usart_putchar(DBG_USART,'r' );
				usart_putchar(DBG_USART,'r' );
				usart_putchar(DBG_USART,'o' );
				usart_putchar(DBG_USART,'r' );
				return -1;
			}
		}

		usart_putchar(DBG_USART,'r' );
		usart_putchar(DBG_USART,'e' );
		usart_putchar(DBG_USART,'c' );
		usart_putchar(DBG_USART,'e' );
		usart_putchar(DBG_USART,'i' );
		usart_putchar(DBG_USART,'v' );
		usart_putchar(DBG_USART,'e' );
		usart_putchar(DBG_USART,'d' );
		usart_putchar(DBG_USART,':' );
		int i;
		for (i=0; i<bytecount;i++)
		{
			usart_putchar(DBG_USART,buffer[i] );
		}


		long timeout = 0;
		long timeout1 = 0;

		while (timeout1 <100000000)
		{

			timeout ++;
			if (timeout == 1000000000)
			{
				timeout1++;
				timeout =0;
			}

		}


	}

	close(hsock);


	return 0;


}



void readControlPins()
{


	usart_putchar(DBG_USART,'\r');
	if (gpio_get_pin_value(nACK ))
	{

		usart_putchar(DBG_USART,'a');
		usart_putchar(DBG_USART,'c');
		usart_putchar(DBG_USART,'k');
		usart_putchar(DBG_USART,'H');
	}
	else if (!gpio_get_pin_value(nACK ))
	{


		usart_putchar(DBG_USART,'a');
		usart_putchar(DBG_USART,'c');
		usart_putchar(DBG_USART,'k');
		usart_putchar(DBG_USART,'L');
	}
	usart_putchar(DBG_USART,' ');
	if (gpio_get_pin_value(BUSY))
	{

		usart_putchar(DBG_USART,'b');
		usart_putchar(DBG_USART,'u');
		usart_putchar(DBG_USART,'s');
		usart_putchar(DBG_USART,'y');
		usart_putchar(DBG_USART,'H');
	}
	else if (!gpio_get_pin_value(BUSY))
	{


		usart_putchar(DBG_USART,'b');
		usart_putchar(DBG_USART,'u');
		usart_putchar(DBG_USART,'s');
		usart_putchar(DBG_USART,'y');
		usart_putchar(DBG_USART,'L');
	}
	usart_putchar(DBG_USART,' ');
	if (gpio_get_pin_value(PAPEREND))
	{

		usart_putchar(DBG_USART,'p');
		usart_putchar(DBG_USART,'a');
		usart_putchar(DBG_USART,'p');
		usart_putchar(DBG_USART,'e');
		usart_putchar(DBG_USART,'r');
		usart_putchar(DBG_USART,'H');
	}
	else if (!gpio_get_pin_value(PAPEREND))
	{

		usart_putchar(DBG_USART,'p');
		usart_putchar(DBG_USART,'a');
		usart_putchar(DBG_USART,'p');
		usart_putchar(DBG_USART,'e');
		usart_putchar(DBG_USART,'r');
		usart_putchar(DBG_USART,'L');
	}
	usart_putchar(DBG_USART,' ');
	if (gpio_get_pin_value(SELECT))
	{

		usart_putchar(DBG_USART,'s');
		usart_putchar(DBG_USART,'e');
		usart_putchar(DBG_USART,'l');
		usart_putchar(DBG_USART,'e');
		usart_putchar(DBG_USART,'c');
		usart_putchar(DBG_USART,'t');
		usart_putchar(DBG_USART,'H');
	}
	else if (!gpio_get_pin_value(SELECT))
	{

		usart_putchar(DBG_USART,'s');
		usart_putchar(DBG_USART,'e');
		usart_putchar(DBG_USART,'l');
		usart_putchar(DBG_USART,'e');
		usart_putchar(DBG_USART,'c');
		usart_putchar(DBG_USART,'t');
		usart_putchar(DBG_USART,'L');
	}
	usart_putchar(DBG_USART,' ');
	if (gpio_get_pin_value(nAUTOLF))
	{

		usart_putchar(DBG_USART,'a');
		usart_putchar(DBG_USART,'u');
		usart_putchar(DBG_USART,'t');

		usart_putchar(DBG_USART,'o');
		usart_putchar(DBG_USART,'H');
	}
	else if (!gpio_get_pin_value(nAUTOLF))
	{

		usart_putchar(DBG_USART,'a');
		usart_putchar(DBG_USART,'u');
		usart_putchar(DBG_USART,'t');

		usart_putchar(DBG_USART,'o');

		usart_putchar(DBG_USART,'L');
	}
	usart_putchar(DBG_USART,' ');
	if (gpio_get_pin_value(nERROR))
	{

		usart_putchar(DBG_USART,'E');
		usart_putchar(DBG_USART,'R');
		usart_putchar(DBG_USART,'R');
		usart_putchar(DBG_USART,'O');
		usart_putchar(DBG_USART,'R');

		usart_putchar(DBG_USART,'H');
	}
	else if (!gpio_get_pin_value(nERROR))
	{

		usart_putchar(DBG_USART,'E');
		usart_putchar(DBG_USART,'R');
		usart_putchar(DBG_USART,'R');
		usart_putchar(DBG_USART,'O');
		usart_putchar(DBG_USART,'R');

		usart_putchar(DBG_USART,'L');
	}
	usart_putchar(DBG_USART,' ');
	if (gpio_get_pin_value(nINIT))
	{

		usart_putchar(DBG_USART,'I');
		usart_putchar(DBG_USART,'N');
		usart_putchar(DBG_USART,'I');
		usart_putchar(DBG_USART,'T');
		usart_putchar(DBG_USART,'H');
	}
	else if (!gpio_get_pin_value(nINIT))
	{


		usart_putchar(DBG_USART,'I');
		usart_putchar(DBG_USART,'N');
		usart_putchar(DBG_USART,'I');
		usart_putchar(DBG_USART,'T');
		usart_putchar(DBG_USART,'L');
	}
	usart_putchar(DBG_USART,' ');

	if (gpio_get_pin_value(nSELECTIN))
	{

		usart_putchar(DBG_USART,'n');
		usart_putchar(DBG_USART,'s');
		usart_putchar(DBG_USART,'e');
		usart_putchar(DBG_USART,'l');
		usart_putchar(DBG_USART,'e');
		usart_putchar(DBG_USART,'c');
		usart_putchar(DBG_USART,'t');
		usart_putchar(DBG_USART,'H');
	}
	else if (!gpio_get_pin_value(nSELECTIN))
	{


		usart_putchar(DBG_USART,'n');
		usart_putchar(DBG_USART,'s');
		usart_putchar(DBG_USART,'e');
		usart_putchar(DBG_USART,'l');
		usart_putchar(DBG_USART,'e');
		usart_putchar(DBG_USART,'c');
		usart_putchar(DBG_USART,'t');
		usart_putchar(DBG_USART,'L');
	}
	usart_putchar(DBG_USART,' ');

	if (gpio_get_pin_value(nSTROBE))
	{

		usart_putchar(DBG_USART,'S');
		usart_putchar(DBG_USART,'t');
		usart_putchar(DBG_USART,'r');
		usart_putchar(DBG_USART,'o');
		usart_putchar(DBG_USART,'b');
		usart_putchar(DBG_USART,'H');
	}
	else if (!gpio_get_pin_value(nSTROBE))
	{


		usart_putchar(DBG_USART,'S');
		usart_putchar(DBG_USART,'t');
		usart_putchar(DBG_USART,'r');
		usart_putchar(DBG_USART,'o');
		usart_putchar(DBG_USART,'b');
		usart_putchar(DBG_USART,'L');
	}
	usart_putchar(DBG_USART,' ');
}




void readDataPins()
{  usart_putchar(DBG_USART,' ');
if (gpio_get_pin_value(DATA1))
{
	usart_putchar(DBG_USART,'D');
	usart_putchar(DBG_USART,'0');
	usart_putchar(DBG_USART,'H');
}

else if (!gpio_get_pin_value(DATA1))
{

	usart_putchar(DBG_USART,'D');
	usart_putchar(DBG_USART,'0');
	usart_putchar(DBG_USART,'L');
}
usart_putchar(DBG_USART,' ');
if (gpio_get_pin_value(DATA2))
{
	usart_putchar(DBG_USART,'D');
	usart_putchar(DBG_USART,'1');
	usart_putchar(DBG_USART,'H');
}
else if (!gpio_get_pin_value(DATA2))
{

	usart_putchar(DBG_USART,'D');
	usart_putchar(DBG_USART,'1');
	usart_putchar(DBG_USART,'L');
}
usart_putchar(DBG_USART,' ');
if (gpio_get_pin_value(DATA3))
{
	usart_putchar(DBG_USART,'D');
	usart_putchar(DBG_USART,'2');
	usart_putchar(DBG_USART,'H');
}
else if (!gpio_get_pin_value(DATA3))
{

	usart_putchar(DBG_USART,'D');
	usart_putchar(DBG_USART,'2');
	usart_putchar(DBG_USART,'L');
}
usart_putchar(DBG_USART,' ');
if (gpio_get_pin_value(DATA4))
{
	usart_putchar(DBG_USART,'D');
	usart_putchar(DBG_USART,'3');
	usart_putchar(DBG_USART,'H');
}
else if (!gpio_get_pin_value(DATA4))
{

	usart_putchar(DBG_USART,'D');
	usart_putchar(DBG_USART,'3');
	usart_putchar(DBG_USART,'L');
}
usart_putchar(DBG_USART,' ');
if (gpio_get_pin_value(DATA5))
{
	usart_putchar(DBG_USART,'D');
	usart_putchar(DBG_USART,'4');
	usart_putchar(DBG_USART,'H');
}
else if (!gpio_get_pin_value(DATA5))
{

	usart_putchar(DBG_USART,'D');
	usart_putchar(DBG_USART,'4');
	usart_putchar(DBG_USART,'L');
}
usart_putchar(DBG_USART,' ');
if (gpio_get_pin_value(DATA6))
{
	usart_putchar(DBG_USART,'D');
	usart_putchar(DBG_USART,'5');
	usart_putchar(DBG_USART,'H');
}
else if (!gpio_get_pin_value(DATA6))
{

	usart_putchar(DBG_USART,'D');
	usart_putchar(DBG_USART,'5');
	usart_putchar(DBG_USART,'L');
}
usart_putchar(DBG_USART,' ');
if (gpio_get_pin_value(DATA7))
{
	usart_putchar(DBG_USART,'D');
	usart_putchar(DBG_USART,'6');
	usart_putchar(DBG_USART,'H');
}
else if (!gpio_get_pin_value(DATA7))
{

	usart_putchar(DBG_USART,'D');
	usart_putchar(DBG_USART,'6');
	usart_putchar(DBG_USART,'L');
}
usart_putchar(DBG_USART,' ');
if (gpio_get_pin_value(DATA8))
{
	usart_putchar(DBG_USART,'D');
	usart_putchar(DBG_USART,'7');
	usart_putchar(DBG_USART,'H');
}

else if (!gpio_get_pin_value(DATA8))
{

	usart_putchar(DBG_USART,'D');
	usart_putchar(DBG_USART,'7');
	usart_putchar(DBG_USART,'L');
}
}


#endif
